package com.legendframework.core.dao.extension.service;

import com.legendframework.core.dao.DataResources;
import com.legendframework.core.dao.exception.ServiceException;
import com.legendframework.core.dao.transaction.JdbcTransaction;
import com.legendframework.core.dao.transaction.YamlTransaction;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * Service生成器
 *
 * 生成Servcie是实现类
 *
 */
public class ServiceGenerate {

    private ServiceGenerate(){}

    /**
     * 根据实体类字节码对象生成Dao对象
     * @param serviceCls 实体类字节码对象
     * @param dataResources 数据底层所需数据
     * @param iocHandle IOC容器处理器，预期是需要外层IOC提供实现方法对Service实现类进行动态代理，动态注入
     * @param <S> 实体类类型
     * @return Service对象
     */
    public static <S extends IService> S generate(Class<S> serviceCls , DataResources dataResources, Function<Object,Object> iocHandle,JdbcTransaction jdbcTransaction,YamlTransaction yamlTransaction){
        try {
            Constructor<S> constructor = serviceCls.getDeclaredConstructor();
            constructor.setAccessible(true);
            S s = constructor.newInstance();
            //获取generateEntityDao方法
            Method generateEntityDaoMethod = BaseService.class.getDeclaredMethod("generateEntityDao", DataResources.class, Function.class,JdbcTransaction.class,YamlTransaction.class);
            generateEntityDaoMethod.setAccessible(true);
            //初始化Service
            generateEntityDaoMethod.invoke(s,dataResources,iocHandle,jdbcTransaction,yamlTransaction);
            return s;
        } catch (Throwable e) {
            throw new ServiceException(e);
        }
    }

    /**
     * 根据实体类字节码对象生成Dao对象
     * @param serviceCls 实体类字节码对象
     * @param dataResources 数据底层所需数据
     * @param <S> 实体类类型
     * @return Service对象
     */
    public static <S extends IService> S generate(Class<S> serviceCls , DataResources dataResources,JdbcTransaction jdbcTransaction,YamlTransaction yamlTransaction){
        return generate(serviceCls,dataResources,item -> item,jdbcTransaction,yamlTransaction);
    }
}
